#include "Room.h"
#include "ServerPlayer.h"

#include <QTcpSocket>

Room::Room(QObject *parent) :
    QTcpServer(parent)
{
    phase = Waiting;

    connect(this, SIGNAL(newConnection()), this, SLOT(addNewPlayer()));
}

QString Room::getRoomName() const{
    return room_name;
}

void Room::setRoomName(const QString &name){
    room_name = name;
}

Room::Phase Room::getPhase() const{
    return phase;
}

QString Room::getPhaseString() const{
    switch(phase){
    case Waiting:
        return "waiting";
    case Playing:
        return "playing";
    }

    return NULL;
}

int Room::getMaxPlayerNum() const{
    return max_player_num;
}

void Room::setMaxPlayerNum(int num){
    max_player_num = num;
}

void Room::startGame(){
    broadcast(Chat, tr("Game starts now!"));
    current_player = players.at(0);
    activateCurrentPlayer();
}

void Room::endGame(){
    QString winner = current_player->getPlayerName();
    deactivateCurrentPlayer();
}

void Room::activateCurrentPlayer(){
    broadcast(Chat, current_player->getPlayerName() + tr("'s round starts."));
    current_player->setPhase(Player::Start);
    sendPlayerProperty(current_player, "phase", "start");
}

void Room::deactivateCurrentPlayer(){
    broadcast(Chat, current_player->getPlayerName() + tr("'s round ends."));
    current_player->setPhase(Player::Inactive);
    sendPlayerProperty(current_player, "phase", "inactive");
}

void Room::nextPlayer(){
    int next_id = current_player->getPlayerId();
    if(next_id >= players.length()){
        next_id = 0;
    }
    current_player = players.at(next_id);
}

void Room::activateNextPlayer(){
    deactivateCurrentPlayer();
    nextPlayer();
    activateCurrentPlayer();
}

void Room::sendChatMessage(ServerPlayer *player, const QString &message){
    if(player != NULL){
        broadcast(Chat, QString("%1 %2").arg(player->getPlayerName()).arg(message));
    }
}

void Room::sendSystemMessage(const QString &message){
    broadcast(Chat, message);
}

void Room::sendMovePieceAction(int player_id, int from, int to){
    broadcast(MovePiece, QString("%1 %2 %3").arg(player_id).arg(from).arg(to));
}

void Room::sendPlayerProperty(ServerPlayer *player, const QString &p_key, const QString &p_value){
    broadcast(SetPlayer, QString("%1 %2 %3").arg(player->getPlayerId()).arg(p_key).arg(p_value));
}

//可能需要修改为UDP广播
void Room::broadcast(CommandType command, const QByteArray &data){
    static char command_str[2] = {0};
    command_str[0] = '0' + (char) command;

    qDebug() << "Room: Broadcasting command =" << command_str;
    foreach(QTcpSocket *socket, player_sockets){
        socket->write(command_str);
        socket->write("=");
        socket->write(data.toBase64());
        socket->write("\n");
    }
}

void Room::broadcast(CommandType command, const QString &data){
    broadcast(command, data.toUtf8());
}

void Room::addNewPlayer(){
    if(player_sockets.length() >= max_player_num){
        return;
    }

    QTcpSocket *socket = nextPendingConnection();
    ServerPlayer *player = new ServerPlayer(this, players.length() + 1, socket);

    foreach(ServerPlayer *other, players){
        player->notify(NewPlayer, other->toString());
    }

    player_sockets.append(socket);
    players.append(player);

    emit playerNumChanged(players.length());
}

void Room::setConfig(qint16 port, const QString &name, int max_player_num){
    if(!isListening()){
        listen(QHostAddress::Any, port);
        setRoomName(name);
        setMaxPlayerNum(max_player_num);

        emit serverPortChanged(port);
        emit serverNameChanged(name);
        emit playerNumChanged(0);
        ready_player_num = 0;

    }else{
        emit occurError(tr("Server is already running."));
    }
}

void Room::addReadyPlayer(){
    ready_player_num++;

    qDebug() << "Room: Ready Player Num = " << ready_player_num;

    if(ready_player_num == max_player_num){
        startGame();
    }
}
